const mysql = require('mysql2/promise');
require('dotenv').config({ path: '../../.env' });

class ConfigService {
  constructor() {
    this.configCache = new Map();
    this.cacheExpiry = 5 * 60 * 1000; // 5分钟缓存
    this.lastCacheUpdate = 0;
  }

  // 获取数据库连接（使用环境变量作为初始连接）
  async getConnection() {
    return mysql.createConnection({
      host: process.env.DB_HOST,
      port: process.env.DB_PORT,
      user: process.env.DB_USER,
      password: process.env.DB_PASSWORD,
      database: process.env.DB_NAME
    });
  }

  // 从数据库获取配置
  async loadConfigFromDatabase() {
    try {
      const connection = await this.getConnection();
      
      const [rows] = await connection.execute(
        'SELECT config_key, config_value, config_type FROM system_config'
      );
      
      await connection.end();
      
      const config = {};
      rows.forEach(row => {
        let value = row.config_value;
        
        // 根据类型转换值
        switch (row.config_type) {
          case 'number':
            value = Number(value);
            break;
          case 'boolean':
            value = value === 'true';
            break;
          case 'json':
            try {
              value = JSON.parse(value);
            } catch (e) {
              console.warn(`Failed to parse JSON config for ${row.config_key}:`, e.message);
            }
            break;
          default:
            // string类型保持原样
            break;
        }
        
        config[row.config_key] = value;
      });
      
      return config;
    } catch (error) {
      console.error('Failed to load config from database:', error);
      throw error;
    }
  }

  // 获取配置值（带缓存）
  async getConfig(key) {
    // 检查缓存是否过期
    const now = Date.now();
    if (now - this.lastCacheUpdate > this.cacheExpiry || this.configCache.size === 0) {
      try {
        const config = await this.loadConfigFromDatabase();
        this.configCache.clear();
        Object.entries(config).forEach(([k, v]) => {
          this.configCache.set(k, v);
        });
        this.lastCacheUpdate = now;
        console.log('Config cache updated from database');
      } catch (error) {
        console.error('Failed to update config cache:', error);
        // 如果数据库连接失败，返回环境变量作为后备
        return process.env[key];
      }
    }
    
    return this.configCache.get(key) || process.env[key];
  }

  // 获取多个配置值
  async getConfigs(keys) {
    const configs = {};
    for (const key of keys) {
      configs[key] = await this.getConfig(key);
    }
    return configs;
  }

  // 更新配置值
  async updateConfig(key, value, type = 'string', category = 'custom') {
    try {
      const connection = await this.getConnection();
      
      let configValue = value;
      if (type === 'json') {
        configValue = JSON.stringify(value);
      } else {
        configValue = String(value);
      }
      
      await connection.execute(
        'INSERT INTO system_config (config_key, config_value, config_type, category) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE config_value = ?, updated_at = CURRENT_TIMESTAMP',
        [key, configValue, type, category, configValue]
      );
      
      await connection.end();
      
      // 更新缓存
      this.configCache.set(key, value);
      
      console.log(`Config updated: ${key} = ${value}`);
      return true;
    } catch (error) {
      console.error(`Failed to update config ${key}:`, error);
      throw error;
    }
  }

  // 获取所有配置（按分类）
  async getAllConfigs() {
    try {
      const connection = await this.getConnection();
      
      const [rows] = await connection.execute(
        'SELECT config_key, config_value, config_type, category, description, is_sensitive FROM system_config ORDER BY category, config_key'
      );
      
      await connection.end();
      
      const configs = {};
      rows.forEach(row => {
        if (!configs[row.category]) {
          configs[row.category] = {};
        }
        
        let value = row.config_value;
        if (row.config_type === 'number') {
          value = Number(value);
        } else if (row.config_type === 'boolean') {
          value = value === 'true';
        } else if (row.config_type === 'json') {
          try {
            value = JSON.parse(value);
          } catch (e) {
            console.warn(`Failed to parse JSON config for ${row.config_key}:`, e.message);
          }
        }
        
        configs[row.category][row.config_key] = {
          value,
          type: row.config_type,
          description: row.description,
          isSensitive: row.is_sensitive
        };
      });
      
      return configs;
    } catch (error) {
      console.error('Failed to get all configs:', error);
      throw error;
    }
  }

  // 清除缓存
  clearCache() {
    this.configCache.clear();
    this.lastCacheUpdate = 0;
    console.log('Config cache cleared');
  }

  // 获取数据库配置（用于初始化数据库连接）
  async getDatabaseConfig() {
    return {
      host: await this.getConfig('DB_HOST'),
      port: await this.getConfig('DB_PORT'),
      user: await this.getConfig('DB_USER'),
      password: await this.getConfig('DB_PASSWORD'),
      database: await this.getConfig('DB_NAME')
    };
  }

  // 获取JWT配置
  async getJWTConfig() {
    return {
      secret: await this.getConfig('JWT_SECRET'),
      expiresIn: await this.getConfig('JWT_EXPIRES_IN'),
      bcryptRounds: await this.getConfig('BCRYPT_ROUNDS')
    };
  }

  // 获取邮箱配置
  async getEmailConfig() {
    return {
      host: await this.getConfig('EMAIL_HOST'),
      port: await this.getConfig('EMAIL_PORT'),
      user: await this.getConfig('EMAIL_USER'),
      pass: await this.getConfig('EMAIL_PASS'),
      from: await this.getConfig('EMAIL_FROM')
    };
  }

  // 获取阿里云AI配置
  async getAIConfig() {
    return {
      apiKey: await this.getConfig('ALIYUN_API_KEY'),
      model: await this.getConfig('ALIYUN_MODEL')
    };
  }

  // 获取文件上传配置
  async getUploadConfig() {
    return {
      uploadPath: await this.getConfig('UPLOAD_PATH'),
      maxFileSize: await this.getConfig('MAX_FILE_SIZE'),
      allowedFileTypes: await this.getConfig('ALLOWED_FILE_TYPES')
    };
  }

  // 获取Redis配置
  async getRedisConfig() {
    return {
      host: await this.getConfig('REDIS_HOST'),
      port: await this.getConfig('REDIS_PORT'),
      password: await this.getConfig('REDIS_PASSWORD')
    };
  }

  // 获取限流配置
  async getRateLimitConfig() {
    return {
      window: await this.getConfig('RATE_LIMIT_WINDOW'),
      max: await this.getConfig('RATE_LIMIT_MAX')
    };
  }
}

// 创建单例实例
const configService = new ConfigService();

module.exports = configService;
